package org.jside.cdn;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jside.jsi.tools.JSAToolkit;
import org.jside.jsi.tools.JavaScriptAnalysisResult;
import org.xidea.el.json.JSONDecoder;
import org.xidea.lite.parser.ParseContext;
import org.xidea.lite.parser.ResultItem;

public class ScriptContext implements ResultItem {
	private static final Log log = LogFactory.getLog(ScriptContext.class);
	private List<String> scripts = new ArrayList<String>();
	private List<String> paths = new ArrayList<String>();
	private String src;
	private ParseContext context;

	public ScriptContext(ParseContext context) {
		this.context = context;
	}

	public void addScript(String script) {
		this.scripts.add(script);
	}

	public void addPath(String script) {
		this.paths.add(script);
	}

	@Override
	public List<Object> compile() {
		Map<String, Object> result = (Map<String, Object>) loadPackageInfo();
		StringBuilder buf = new StringBuilder();
		for (String script : scripts) {
			buf.append(script);
			buf.append("\n");
		}
		JavaScriptAnalysisResult jsar = JSAToolkit.getInstance()
				.createJavaScriptCompressor().analyse(buf.toString());

		Collection<String> pathList = (Collection<String>) result
				.get("pathList");
		Map<String, Collection<String>> packageMap = (Map<String, Collection<String>>) result
				.get("packageMap");
		ArrayList<String> externalVars = new ArrayList<String>(jsar
				.getExternalVars());
		buf = new StringBuilder(this.src);
		for (String path : pathList) {
			buf.append(path);
			buf.append("+");
			externalVars.remove(path.substring(path.lastIndexOf(':') + 1));
		}
		for (String var : externalVars) {
			for (String key : packageMap.keySet()) {
				Collection<String> values = packageMap.get(key);
				if (values.contains(var)) {
					buf.append(key + ":" + var);
					buf.append("+");
					// externalVars.remove(var);
					break;
				}
			}
		}
		buf.deleteCharAt(buf.length() - 1);
		return Arrays.asList((Object) buf.toString());
	}

	/**
	 * { "pathList":[ "org.xidea.jsidoc.util:$log", "org.jside:Request","
	 * "org.jside:Cookie" ], "packageMap":{
	 * "org.jside":["Draggable","Tween","TweenRuleSample"] } }
	 * 
	 * @return
	 */
	public Map<String, Object> loadPackageInfo() {
		try {
			CDNServlet cdn = CDNServlet.instance;
			String result;
			StringBuilder url = new StringBuilder();
			for (String path : paths) {
				url.append(path);
				url.append("+");
			}
			url.deleteCharAt(url.length() - 1);
			if (cdn == null) {
				// String url = "http://jsicdn.appspot.com/cdn/=";
				// StringBuilder url = new
				// StringBuilder("http://localhost:8080/cdn/=");
				String cdnPath = 
						"http://jsicdn.appspot.com/cdn/=" + url;

				// context.getFeatrue("http://www.xidea.org/ns/lite/cdnroot/");
				HttpURLConnection connection = (HttpURLConnection) new URL(cdnPath).openConnection();
				connection.setDoOutput(true);
				connection.setRequestMethod("POST");
				// connection.setRequestProperty("use_intranet", "true");
				// http.setRequestProperty("Content-Length", "0");
				OutputStreamWriter writer = new OutputStreamWriter(connection
						.getOutputStream());
				writer.write("test=1");
				writer.close();
				result = loadText(connection
						.getInputStream());
			}else{
				result = cdn.queryExportInfo(url.toString());
			}
			return (Map<String, Object>) JSONDecoder.decode(result);
		} catch (Exception e) {
			log.error("查询包信息数据", e);
			throw new RuntimeException(e);
		}
	}

	public String loadText(InputStream in) throws IOException {
		InputStreamReader reader = new InputStreamReader(in, "UTF-8");
		char[] buf = new char[1024];
		StringBuilder result = new StringBuilder();
		int count;
		while ((count = reader.read(buf)) >= 0) {
			result.append(buf, 0, count);
		}
		in.close();
		return result.toString();
	}

	public void setSrc(String src) {
		this.src = src.substring(0, src.indexOf("/=") + 2);
	}
}